#include "Lexer.h"
#include "Parser.h"
#include "SemanticAnalyzer.h"
#include "SymbolTable.h"
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>

void printCompilerMenu() {
    std::cout << "\n" << std::string(60, '=') << std::endl;
    std::cout << "🎯 SQL编译器交互体验系统" << std::endl;
    std::cout << std::string(60, '=') << std::endl;
    std::cout << "1. 📝 输入SQL语句进行编译" << std::endl;
    std::cout << "2. 🔍 查看词法分析结果" << std::endl;
    std::cout << "3. 🌳 查看语法分析结果(AST)" << std::endl;
    std::cout << "4. ✅ 查看语义分析结果" << std::endl;
    std::cout << "5. 📋 查看符号表" << std::endl;
    std::cout << "6. 📊 查看编译器统计" << std::endl;
    std::cout << "7. 🧹 清空符号表" << std::endl;
    std::cout << "8. 📖 显示支持的SQL语法" << std::endl;
    std::cout << "0. 🚪 退出系统" << std::endl;
    std::cout << std::string(60, '=') << std::endl;
    std::cout << "请选择操作 (0-8): ";
}

void showSupportedSQL() {
    std::cout << "\n📖 支持的SQL语句类型:" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    std::cout << "1. CREATE TABLE 语句:" << std::endl;
    std::cout << "   CREATE TABLE table_name (" << std::endl;
    std::cout << "       column_name data_type [constraints]," << std::endl;
    std::cout << "       ..." << std::endl;
    std::cout << "   );" << std::endl;
    std::cout << "   示例: CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(50) NOT NULL);" << std::endl;

    std::cout << "\n2. INSERT 语句:" << std::endl;
    std::cout << "   INSERT INTO table_name VALUES (value1, value2, ...);" << std::endl;
    std::cout << "   示例: INSERT INTO users VALUES (1, 'Alice', 25);" << std::endl;

    std::cout << "\n3. SELECT 语句:" << std::endl;
    std::cout << "   SELECT [columns] FROM table_name [WHERE condition];" << std::endl;
    std::cout << "   示例: SELECT * FROM users WHERE age > 20;" << std::endl;

    std::cout << "\n4. UPDATE 语句:" << std::endl;
    std::cout << "   UPDATE table_name SET column = value WHERE condition;" << std::endl;

    std::cout << "\n5. DELETE 语句:" << std::endl;
    std::cout << "   DELETE FROM table_name WHERE condition;" << std::endl;

    std::cout << "\n🔧 支持的数据类型:" << std::endl;
    std::cout << "   • INT - 整数类型" << std::endl;
    std::cout << "   • VARCHAR(n) - 可变长度字符串" << std::endl;
    std::cout << "   • FLOAT - 浮点数类型" << std::endl;
    std::cout << "   • BOOLEAN - 布尔类型" << std::endl;

    std::cout << "\n🔧 支持的约束:" << std::endl;
    std::cout << "   • PRIMARY KEY - 主键约束" << std::endl;
    std::cout << "   • NOT NULL - 非空约束" << std::endl;
    std::cout << "   • UNIQUE - 唯一约束" << std::endl;

    std::cout << "\n🔧 支持的操作符:" << std::endl;
    std::cout << "   • 比较: =, !=, >, <, >=, <=" << std::endl;
    std::cout << "   • 逻辑: AND, OR, NOT" << std::endl;
    std::cout << "   • 模式匹配: LIKE" << std::endl;
}

void compileSQL(const std::string& sql, std::vector<MiniDB::Token>& tokens,
                std::vector<std::shared_ptr<MiniDB::Statement>>& statements,
                MiniDB::SymbolTable& symbol_table) {

    std::cout << "\n🔄 正在编译SQL语句..." << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    try {
        // 1. 词法分析
        std::cout << "📝 第1步: 词法分析..." << std::endl;
        MiniDB::Lexer lexer(sql);
        tokens = lexer.tokenize();
        std::cout << "✅ 词法分析完成，识别到 " << tokens.size() << " 个词法单元" << std::endl;

        // 2. 语法分析
        std::cout << "\n🌳 第2步: 语法分析..." << std::endl;
        MiniDB::Parser parser(tokens);
        statements = parser.parse();
        std::cout << "✅ 语法分析完成，构建了 " << statements.size() << " 个语句的AST" << std::endl;

        // 3. 语义分析
        std::cout << "\n✅ 第3步: 语义分析..." << std::endl;
        MiniDB::SemanticAnalyzer semantic_analyzer(symbol_table);
        bool semantic_ok = semantic_analyzer.analyze(statements);

        if (semantic_ok && !semantic_analyzer.hasErrors()) {
            std::cout << "✅ 语义分析完成，未发现错误" << std::endl;
        } else {
            std::cout << "⚠️  语义分析完成，发现 " << semantic_analyzer.getErrors().size() << " 个错误" << std::endl;
            for (const auto& error : semantic_analyzer.getErrors()) {
                std::cout << "   • [" << error.error_type << "] " << error.message << std::endl;
            }
        }

    } catch (const std::exception& e) {
        std::cerr << "❌ 编译失败: " << e.what() << std::endl;
    }
}

void showTokens(const std::vector<MiniDB::Token>& tokens) {
    std::cout << "\n🔍 词法分析结果:" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    if (tokens.empty()) {
        std::cout << "暂无词法单元" << std::endl;
        return;
    }

    std::cout << std::left << std::setw(15) << "词法单元类型"
              << std::setw(20) << "词素值"
              << std::setw(8) << "行号"
              << "列号" << std::endl;
    std::cout << std::string(60, '-') << std::endl;

    for (size_t i = 0; i < tokens.size() && i < 20; ++i) { // 最多显示20个
        const auto& token = tokens[i];
        if (token.type != MiniDB::TokenType::EOF_TOKEN) {
            std::string type_name;
            switch (token.type) {
                case MiniDB::TokenType::CREATE: type_name = "CREATE"; break;
                case MiniDB::TokenType::TABLE: type_name = "TABLE"; break;
                case MiniDB::TokenType::SELECT: type_name = "SELECT"; break;
                case MiniDB::TokenType::INSERT: type_name = "INSERT"; break;
                case MiniDB::TokenType::UPDATE: type_name = "UPDATE"; break;
                case MiniDB::TokenType::DELETE: type_name = "DELETE"; break;
                case MiniDB::TokenType::IDENTIFIER: type_name = "IDENTIFIER"; break;
                case MiniDB::TokenType::STRING_LITERAL: type_name = "STRING"; break;
                case MiniDB::TokenType::NUMBER_LITERAL: type_name = "NUMBER"; break;
                case MiniDB::TokenType::INT: type_name = "INT"; break;
                case MiniDB::TokenType::VARCHAR: type_name = "VARCHAR"; break;
                default: type_name = "OTHER"; break;
            }

            std::cout << std::left << std::setw(15) << type_name
                      << std::setw(20) << ("'" + token.value + "'")
                      << std::setw(8) << token.line
                      << token.column << std::endl;
        }
    }

    if (tokens.size() > 20) {
        std::cout << "... (还有 " << (tokens.size() - 20) << " 个词法单元)" << std::endl;
    }
}

void showAST(const std::vector<std::shared_ptr<MiniDB::Statement>>& statements) {
    std::cout << "\n🌳 语法分析结果 (AST):" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    if (statements.empty()) {
        std::cout << "暂无语句" << std::endl;
        return;
    }

    for (size_t i = 0; i < statements.size(); ++i) {
        std::cout << "\n语句 " << (i + 1) << ":" << std::endl;

        if (auto create_stmt = std::dynamic_pointer_cast<MiniDB::CreateTableStatement>(statements[i])) {
            std::cout << "🏗️  CreateTable: " << create_stmt->table_name << std::endl;
            for (const auto& col_node : create_stmt->columns) {
                if (auto col_def = std::dynamic_pointer_cast<MiniDB::ColumnDefinition>(col_node)) {
                    std::cout << "   📋 Column: " << col_def->column_name << " " << col_def->data_type;
                    if (!col_def->constraints.empty()) {
                        std::cout << " (";
                        for (size_t j = 0; j < col_def->constraints.size(); ++j) {
                            std::cout << col_def->constraints[j];
                            if (j < col_def->constraints.size() - 1) std::cout << ", ";
                        }
                        std::cout << ")";
                    }
                    std::cout << std::endl;
                }
            }
        } else if (auto insert_stmt = std::dynamic_pointer_cast<MiniDB::InsertStatement>(statements[i])) {
            std::cout << "➕ InsertStatement:" << std::endl;
            std::cout << "   📋 Table: " << insert_stmt->table_name << std::endl;
            if (!insert_stmt->values.empty()) {
                std::cout << "   📊 Values:" << std::endl;
                for (size_t j = 0; j < insert_stmt->values[0].size(); ++j) {
                    if (auto literal = std::dynamic_pointer_cast<MiniDB::Literal>(insert_stmt->values[0][j])) {
                        std::cout << "      • ";
                        if (std::holds_alternative<int>(literal->value)) {
                            std::cout << std::get<int>(literal->value);
                        } else if (std::holds_alternative<std::string>(literal->value)) {
                            std::cout << "'" << std::get<std::string>(literal->value) << "'";
                        } else if (std::holds_alternative<double>(literal->value)) {
                            std::cout << std::get<double>(literal->value);
                        }
                        std::cout << " (" << literal->value_type << ")" << std::endl;
                    }
                }
            }
        } else if (auto select_stmt = std::dynamic_pointer_cast<MiniDB::SelectStatement>(statements[i])) {
            std::cout << "🔍 SelectStatement:" << std::endl;
            std::cout << "   📋 From: ";
            if (auto from_clause = std::dynamic_pointer_cast<MiniDB::FromClause>(select_stmt->from_clause)) {
                std::cout << from_clause->table_name << std::endl;
            }
            if (select_stmt->where_clause) {
                std::cout << "   🎯 Where: [条件表达式]" << std::endl;
            }
        }
    }
}

void showSymbolTable(MiniDB::SymbolTable& symbol_table) {
    std::cout << "\n📋 符号表内容:" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    auto table_names = symbol_table.getTableNames();
    if (table_names.empty()) {
        std::cout << "符号表为空" << std::endl;
        return;
    }

    for (const std::string& table_name : table_names) {
        const MiniDB::TableInfo* table_info = symbol_table.getTable(table_name);
        if (table_info) {
            std::cout << "📊 表: " << table_name << std::endl;
            std::cout << "   📋 列信息:" << std::endl;

            for (const auto& column : table_info->columns) {
                std::string type_str;
                switch (column.type) {
                    case MiniDB::DataType::INT: type_str = "INT"; break;
                    case MiniDB::DataType::VARCHAR: type_str = "VARCHAR"; break;
                    case MiniDB::DataType::FLOAT: type_str = "FLOAT"; break;
                    case MiniDB::DataType::BOOLEAN: type_str = "BOOLEAN"; break;
                    case MiniDB::DataType::DATE: type_str = "DATE"; break;
                    case MiniDB::DataType::TEXT: type_str = "TEXT"; break;
                    default: type_str = "UNKNOWN"; break;
                }
                std::cout << "      • " << column.name << " (" << type_str << ")";
                if (column.is_primary_key) std::cout << " [主键]";
                if (!column.nullable) std::cout << " [非空]";
                std::cout << std::endl;
            }
            std::cout << std::endl;
        }
    }
}

void showCompilerStats(const std::vector<MiniDB::Token>& tokens,
                      const std::vector<std::shared_ptr<MiniDB::Statement>>& statements,
                      MiniDB::SymbolTable& symbol_table) {
    std::cout << "\n📊 编译器统计信息:" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    std::cout << "📝 词法单元数量: " << tokens.size() << std::endl;
    std::cout << "🌳 解析的语句数: " << statements.size() << std::endl;
    std::cout << "📋 符号表中的表数: " << symbol_table.getTableNames().size() << std::endl;

    // 统计不同类型的词法单元
    std::unordered_map<std::string, int> token_counts;
    for (const auto& token : tokens) {
        if (token.type == MiniDB::TokenType::IDENTIFIER) {
            token_counts["标识符"]++;
        } else if (token.type == MiniDB::TokenType::STRING_LITERAL) {
            token_counts["字符串字面量"]++;
        } else if (token.type == MiniDB::TokenType::NUMBER_LITERAL) {
            token_counts["数字字面量"]++;
        } else if (token.type == MiniDB::TokenType::CREATE) {
            token_counts["CREATE关键字"]++;
        } else if (token.type == MiniDB::TokenType::SELECT) {
            token_counts["SELECT关键字"]++;
        } else if (token.type == MiniDB::TokenType::INSERT) {
            token_counts["INSERT关键字"]++;
        }
    }

    std::cout << "📊 词法单元类型统计:" << std::endl;
    for (const auto& pair : token_counts) {
        std::cout << "   • " << pair.first << ": " << pair.second << " 个" << std::endl;
    }
}

int main() {
    std::cout << "🚀 SQL编译器交互体验系统启动" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;
    std::cout << "这是一个功能完整的SQL编译器，支持词法分析、语法分析和语义分析" << std::endl;
    std::cout << "可以编译CREATE TABLE, INSERT, SELECT, UPDATE, DELETE等SQL语句" << std::endl;

    MiniDB::SymbolTable symbol_table;
    std::vector<MiniDB::Token> current_tokens;
    std::vector<std::shared_ptr<MiniDB::Statement>> current_statements;

    int choice;
    do {
        printCompilerMenu();
        std::cin >> choice;

        switch (choice) {
            case 1: {
                // 输入SQL语句
                std::cout << "\n📝 请输入SQL语句 (以分号结束):" << std::endl;
                std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

                std::cin.ignore(); // 清除换行符
                std::string sql;
                std::cout << "SQL> ";
                std::getline(std::cin, sql);

                if (!sql.empty()) {
                    compileSQL(sql, current_tokens, current_statements, symbol_table);
                }
                break;
            }

            case 2:
                showTokens(current_tokens);
                break;

            case 3:
                showAST(current_statements);
                break;

            case 4:
                // 语义分析结果已经在编译时显示了
                std::cout << "\n✅ 语义分析结果已在编译过程中显示" << std::endl;
                break;

            case 5:
                showSymbolTable(symbol_table);
                break;

            case 6:
                showCompilerStats(current_tokens, current_statements, symbol_table);
                break;

            case 7:
                symbol_table.clear();
                current_tokens.clear();
                current_statements.clear();
                std::cout << "\n🧹 符号表和编译结果已清空!" << std::endl;
                break;

            case 8:
                showSupportedSQL();
                break;

            case 0:
                std::cout << "\n👋 感谢使用SQL编译器，再见!" << std::endl;
                break;

            default:
                std::cout << "\n❌ 无效选择，请重新输入!" << std::endl;
        }

        if (choice != 0) {
            std::cout << "\n按回车键继续...";
            std::cin.ignore();
            std::cin.get();
        }

    } while (choice != 0);

    return 0;
}
